#include "key.h"
#include "WaterPump.h"
#include "HX710C.h"

u8 key_flag;    //按键标志位
u8 Key_Value;    //存储按键键值
/***************按键引脚初始化*****************/
void Key_Init(void)
{
	GPIO_Config_T gpioConfig;
	RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);
	gpioConfig.mode = GPIO_MODE_IN;
  gpioConfig.pupd = GPIO_PUPD_PD;
  gpioConfig.pin = GPIO_PIN_4;
  GPIO_Config(GPIOB, &gpioConfig);
	
}

/*********************读取按键键值，返回键值***************/
u8 Key_GetSate(void)
{
		return (!GPIO_ReadInputBit(GPIOB,GPIO_PIN_4));
}


/*****************************读取当前按键状态****************/
unsigned char key_driver(void) 
{     
    static unsigned char key_state = 0;
    static unsigned int  key_time = 0;
    unsigned char key_press, key_return; 

    key_return = N_KEY;                         //  清除 返回按键值
    key_press = Key_GetSate();                      //  读取当前键值
    switch (key_state)     
    {       
        case KEY_STATE_0:                       //  按键状态0：判断有无按键按下
            if (!key_press)                     //  有按键按下
            {
                key_time = 0;                   //  清零时间间隔计数
                key_state = KEY_STATE_1;        //  然后进入 按键状态1
            }        
            break;
        case KEY_STATE_1:                       //  按键状态1：软件消抖（确定按键是否有效，而不是误触）。按键有效的定义：按键持续按下超过设定的消抖时间。
            if (!key_press)                     
            {
                key_time++;                     //  一次10ms
                if(key_time>=5)   //  消抖时间为：SINGLE_KEY_TIME*10ms = 30ms;
                {
                    key_state = KEY_STATE_2;    //  如果按键时间超过 消抖时间，即判定为按下的按键有效。按键有效包括两种：单击或者长按，进入 按键状态2， 继续判定到底是那种有效按键
                }
            }         
            else key_state = KEY_STATE_0;       //  如果按键时间没有超过，判定为误触，按键无效，返回 按键状态0，继续等待按键
            break; 
        case KEY_STATE_2:                       //  按键状态2：判定按键有效的种类：是单击，还是长按
            if(key_press)                       //  如果按键在 设定的长按时间 内释放，则判定为单击
            { 
                 key_return = S_KEY;            //  返回 有效按键值：单击
                 key_state = KEY_STATE_0;       //  返回 按键状态0，继续等待按键
            } 
            else
            {
                key_time++;                     

                if(key_time >= 135)   //  如果按键时间超过 设定的长按时间, 则判定为 长按
                {
                    key_return = L_KEY;         //  返回 有效键值值：长按
                    key_state = KEY_STATE_3;    //  去状态3，等待按键释放
                }
            }
            break;
			 case KEY_STATE_3:   
						if(key_press)                       //  如果按键在 设定的长按时间 内释放，则判定为单击
            { 
                 key_state = KEY_STATE_0;       //  返回 按键状态0，继续等待按键
            } 
						break;
			 default:
                 key_state = KEY_STATE_0;   
					break;
		}
		return key_return;
}           

/*********************读取当前按键模式*********************/
u8 key_read(void)                             
{ 
	static unsigned char key_state1=0, key_time1=0;
	unsigned char key_return,key_temp;

	key_return = N_KEY;                         //  清零 返回按键值

	key_temp = key_driver();                    //  读取键值

	switch(key_state1) 
	{         
			case KEY_STATE_0:                       //  按键状态0：等待有效按键（通过 key_driver 返回的有效按键值）
					if (key_temp == S_KEY )             //  如果是[单击]，不马上返回单击按键值，先进入 按键状态1，判断是否有[双击]的可能
					{ 
							 key_time1 = 0;                 //  清零计时
							 key_state1 = KEY_STATE_1; 
					}             
					else                                //  如果不是[单击]，直接返回按键值。这里的按键值可能是：[长按]，[无效按键]
					{
							 key_return = key_temp;         //  返回 按键值
					}
					break;

			case KEY_STATE_1:                       //  按键状态1：判定是否有[双击]
					if (key_temp == S_KEY)              //  有[单击]后，如果在 设定的时间间隔（） 内，再次有[单击]，则为[双击]，但是不马上返回 有效按键值为[双击]，先进入 按键状态2，判断是否有[三击]
					{
							key_time1 = 0;                  //  清零 时间间隔
							key_state1 = KEY_STATE_2;       //  改变 按键状态值
					} 
					else                                //  有[单击]后，如果在 设定的时间间隔（）内，没有[单击]出现，则判定为 [单击]
					{
							key_time1++;                    //  计数 时间间隔
							if(key_time1 >= 35)   //  超过 时间间隔
							 { 
									key_return = S_KEY;         //  返回 有效按键：[单击]
									key_state1 = KEY_STATE_0;   //  返
					
							 }              
					 }              
					 break; 

			case KEY_STATE_2:                       // 按键状态2：判定是否有[三击]
					if (key_temp == S_KEY)              // 有[双击]后，如果在 设定的时间间隔（） 内，再次有[单击]，则为[三击]，由于这里只扩展到[三击]，所以马上返回 有效按键值为[三击]
					{
							key_time1 = 0;                  // 清零 时间间隔
							key_state1 = KEY_STATE_3;       // 改变按键状态值 
					} 
					else                                // 有[双击]后，如果在 设定的时间间隔（）内，没有[单击]，则判定为 [双击]
					{
							key_time1++;                    // 计数 时间间隔
							if(key_time1 >= 35)   // 超过 时间间隔
							 { 
										key_return = D_KEY;       // 返回 有效按键：[双击]
										key_state1 = KEY_STATE_0; // 返回 按键状态0，等待新的有效按键
							 }
					 }
					 break; 

			case KEY_STATE_3:                       // 按键状态3：等待按键释放
					if (key_temp == S_KEY)              // 有[三击]后，如果在 设定的时间间隔（） 内，再次有[单击]，则为[四击]，马上返回有效按键值为[四击]，
					{ 
							 key_return = Q_KEY;            // 返回 有效按键：[四击]
							 key_state1 = KEY_STATE_4;      // 返回 按键状态0，等待新的有效按键
					} 
					else                                
					{                                   // 有[三击]后，如果在 设定的时间间隔（）内，没有[单击]，则判定为 [三击]                 
							key_time1++;                    // 计数 时间间隔
							if(key_time1 >= 35)   // 超过 时间间隔
							 { 
										key_return = T_KEY;       // 返回 有效按键：[三击]
										key_state1 = KEY_STATE_0; // 返回 按键状态0，等待新的有效按键
							 }              
					 }             
					 break; 
					 
			case KEY_STATE_4:                       // 按键状态3：等待按键释放
					if (key_temp == S_KEY)              // 有[三击]后，如果在 设定的时间间隔（） 内，再次有[单击]，则为[四击]，马上返回有效按键值为[四击]，
					{ 
							 key_return = F_KEY;            // 返回 有效按键：[五击]
							 key_state1 = KEY_STATE_0;      // 返回 按键状态0，等待新的有效按键
					} 
					else                                
					{                                   // 有[三击]后，如果在 设定的时间间隔（）内，没有[单击]，则判定为 [三击]                 
							key_time1++;                    // 计数 时间间隔
							if(key_time1 >= 35)        // 超过 时间间隔
							 { 
										key_return = Q_KEY;       // 返回 有效按键：[四击]
										key_state1 = KEY_STATE_0; // 返回 按键状态0，等待新的有效按键
							 }              
					 }             
					 break; 
			default:                                //  特殊情况：key_state是其他值得情况，清零key_state。这种情况一般出现在 没有初始化key_state，第一次执行这个函数的时候
					key_state1 = KEY_STATE_0;
					break;
	}

	return  key_return;                        // 返回 按键值
}

//放到定时器中断里 ，定时器每10ms调用一次
void Key_Tick(void)				
{
	if(KEy_Tick>=1)             //  每过10ms标志位 置1用于按键检测 
	{
		key_flag = 1;
		KEy_Tick=0;
	}
}



u8 switch_1_flag =0;   //开关按键标志位
void Key_button(void)
{
	if(switch_1_flag == 0)         //开关按钮
	{
		KEY_Guess();
	}
	else
	{
		PUMP_stop();
	}


}
void KEY_Guess(void)    
{
		if(key_flag)
		{
				key_flag = 0;        //判断要不要进入
				Check_Pump_Water_state(); //按键模式程序
		}
}



u8 Key_stat = ON_state;  //初始为开机状态     开关机切换状态标志位

u8  Key_WIFI_flag =0;    //WiFi重置标志位
u8  key_mach_flag = continuity_Mode;  //模式切


u8 Key_mach(void)    //开关机状态
{
	Key_Value =	key_read();   //读取键值
//	printf("state = %d,value = %d\r\n",Key_stat,Key_Value);
	
	switch (Key_stat)
	{
		case ON_state:             //开机状态
			{
				if(Key_Value == L_KEY)       //长按
				{
					Key_stat = OFF_state;            //开关机状态切换
					GPIO_SetBit(GPIOB, GPIO_PIN_5);   //WIFi指示灯关
				}
				else if(Key_Value == S_KEY )    //单按
				{
					if(key_mach_flag == continuity_Mode)
					{
						 mcu_dp_enum_update(DPID_WORK_MODE,1);  //上报间歇模式
						key_mach_flag =interval_Mode;		 
					}
					else if(key_mach_flag == interval_Mode)
					{
						mcu_dp_enum_update(DPID_WORK_MODE,0); //上报持续模式
						key_mach_flag =continuity_Mode; 
					}
					else
						break;
//					key_mach_flag = (key_mach_flag == 0) ? 1 : 0;      //单击模式切换
				}
				else if(Key_Value == F_KEY)                            //连按5次
						Key_WIFI_flag = 1;                           // 网络重置标志位
				else
					break;
			}
		break;
		case OFF_state:                             //关机状态
			{
				if(Key_Value == L_KEY)
				{
					Key_stat = ON_state;          //切换开机
					GPIO_ClearBit(GPIOB, GPIO_PIN_5);  //WIFi指示灯开
				}
				else if(Key_Value == F_KEY) 					//关机状态连按5次
				{
					mcu_reset_wifi();    //重置wifi
					delay_ms(1000);
					again_flash_Save(0,0);
					NVIC_SystemReset();                  //系统复位  
				}
				else 
					break;
			}
		break;
	default:
//			Key_stat = OFF_state;         //其他情况为关机   
		break;
	}
return Key_stat;
}








